/**
 * Created by goland
 * User: adam_wang
 * Date: 2024/8/11
 * Time: 上午1:35
 */

package orm

import (
	"github.com/beego/beego/v2/client/orm"
	"strings"
)

// MySqlQueryBuilder
// @Description: MySql查询构造器
type MySqlQueryBuilder struct {
	orm.MySQLQueryBuilder
	whereParams []interface{}
}

// WhereSqlBuilder 根据where条件生成sql语句
// @receiver qb *MySqlQueryBuilder
// @param where []Where
// @return QueryBuilder
func (qb *MySqlQueryBuilder) WhereSqlBuilder(where []Where) QueryBuilder {
	vals := ""

	for key, whereValue := range where {
		switch strings.ToUpper(whereValue.Condition) {
		case "IN":
			switch whereValue.Value.(type) {
			case []string:
				vals = "'" + strings.Join(whereValue.Value.([]string), "','") + "'"
				break
			default:
				vals = whereValue.Value.(string)
			}

			if key == 0 {
				qb.Where("`" + whereValue.Field + "`" + " " + "IN" + "(" + vals + ")")
			} else {
				qb.And("`" + whereValue.Field + "`" + " " + "IN" + "(" + vals + ")")
			}

			break
		case "OR":
			sql := sqlBuilder(whereValue.Value.([]Where), &qb.whereParams, "OR")
			if key == 0 {
				qb.Where("(" + sql + ")")
			} else {
				qb.And("(" + sql + ")")
			}

			break
		case "AND":
			sql := sqlBuilder(whereValue.Value.([]Where), &qb.whereParams, "AND")
			if key == 0 {
				qb.Where("(" + sql + ")")
			} else {
				qb.And("(" + sql + ")")
			}

			break
		default:
			if key == 0 {
				qb.Where("`" + whereValue.Field + "`" + " " + whereValue.Condition + " ?")
			} else {
				qb.And("`" + whereValue.Field + "`" + " " + whereValue.Condition + " ?")
			}

			qb.whereParams = append(qb.whereParams, whereValue.Value)
		}
	}

	return qb
}

// sqlBuilder 递归生成sql语句
// @param where []Where
// @param WhereParams *[]interface{}
// @param condition string
// @return string
func sqlBuilder(where []Where, whereParams *[]interface{}, condition string) string {
	qb, _ := NewQueryBuilder("mysql")
	tmpCondition := ""
	vals := ""

	for key, item := range where {
		switch item.Value.(type) {
		case []Where:
			tmpSql := sqlBuilder(item.Value.([]Where), whereParams, item.Condition)
			if key == 0 {
				qb.Where("(" + tmpSql + ")")
			} else {
				if strings.ToUpper(condition) == "AND" {
					qb.And("(" + tmpSql + ")")
				} else if strings.ToUpper(condition) == "OR" {
					qb.Or("(" + tmpSql + ")")
				}
			}
		default:
			tmpCondition = strings.ToUpper(item.Condition)
			vals = ""

			if tmpCondition == "IN" {
				switch item.Value.(type) {
				case []string:
					vals = "'" + strings.Join(item.Value.([]string), "','") + "'"
					break
				default:
					vals = item.Value.(string)
				}
			}

			switch strings.ToUpper(condition) {
			case "AND":
				if key == 0 {
					if tmpCondition == "IN" {
						qb.Where("`" + item.Field + "`" + " " + "IN" + "(" + vals + ")")
					} else {
						qb.Where("`" + item.Field + "`" + " " + item.Condition + " ?")
					}
				} else {
					if tmpCondition == "IN" {
						qb.And("`" + item.Field + "`" + " " + "IN" + "(" + vals + ")")
					} else {
						qb.And("`" + item.Field + "`" + " " + item.Condition + " ?")
					}
				}

				if tmpCondition != "IN" {
					*whereParams = append(*whereParams, item.Value)
				}

				break
			case "OR":
				if key == 0 {
					if tmpCondition == "IN" {
						qb.Where("`" + item.Field + "`" + " " + "IN" + "(" + vals + ")")
					} else {
						qb.Where("`" + item.Field + "`" + " " + item.Condition + " ?")
					}
				} else {
					if tmpCondition == "IN" {
						qb.Or("`" + item.Field + "`" + " " + "IN" + "(" + vals + ")")
					} else {
						qb.Or("`" + item.Field + "`" + " " + item.Condition + " ?")
					}
				}

				if tmpCondition != "IN" {
					*whereParams = append(*whereParams, item.Value)
				}

				break
			}
		}
	}

	sql := qb.String()
	sql = sql[6:]

	return sql
}

// GetWhereParams 获取where参数
// @receiver qb *MySqlQueryBuilder
// @return []interface{}
func (qb *MySqlQueryBuilder) GetWhereParams() []interface{} {
	return qb.whereParams
}
